using UnityEngine;
using System.Collections.Generic;


//A character with an emotional model, which shifts color based on emotions about other characters
public class Character : MoveableSprite {
	
	//What is the distance at which proximity should reach 0%?
	//This should keep it so everything can always "see" everything
	const float MAX_DIST = 800000;
	
	//The smallest possible distance between two objects (so big because I'm dealing with squared magnitude)
	const float MIN_DIST = 10000;
	
	private const float CHARACTER__NOTE_VOLUME_PERCENT = .4f;
	
	//The list of objects in the world to reason about
	protected List<MentalObject> mentalItems;
	protected List<MentalCharacter> mentalCharacters;
	
	//how much love the character feels based on mental objects around them
	protected float love;
	
	//percent juju - controls your alpha
	private float juju = 1f;
	public float Juju {
		get {return juju;}
		set {if(value > 1) juju = 1;
			else if(value < 0) juju = 0;
			else juju = value;}
	}
	
	// Use this for initialization
	override protected void Start () {
		mentalItems = new List<MentalObject>();
		mentalCharacters = new List<MentalCharacter>();
		noteVolume = CHARACTER__NOTE_VOLUME_PERCENT;
		base.Start();
	}
	
	// Update is called once per frame
	override protected void Update () {
		base.Update();
		updateMentalCharacters();
		updateMentalItemsAndLove();//update mental proximities, the love total based on those, and the audio volumes
		
		
	}
	
	//add a character to this characters list of other characters
	public void addMentalCharacter(Character c) {
		MentalCharacter mC = new MentalCharacter(c, c.gameObject, 0, .5f);
		mentalCharacters.Add(mC);
	}
	
	public void addMentalItem(ItemScript item) {
		MentalObject mO = new MentalObject(item.gameObject, 0, .5f);
		mentalItems.Add (mO);
	}
	
	//Update this character's mental items and love level
	protected virtual void updateMentalItemsAndLove() {
		
		float loveTotal = 0f;
		if(mentalItems.Count == 0) {
			love = .5f;
			return;
		}
		foreach(MentalObject mO in mentalItems) {
			updateProx(mO);
			updateLike(mO);
			if(mO.Prox == 0) loveTotal += .5f;//indifference
			else loveTotal += mO.Like * mO.Prox;
		}
		float avgLove = loveTotal/mentalItems.Count;
		love = avgLove;
	}
	
	protected virtual void updateMentalCharacters() {
		//update the character proximities
		foreach (MentalCharacter mO in mentalCharacters) {
			updateProx(mO);
		}
	}
	
	private void updateLike(MentalObject mO) {
		if(!mO.isPlaying()) mO.Like = .5f;//keep silent objects neutral
		mO.Like = getHarmonyPercent(mO.getNote());//so that like stays between -.5 and +.5
	}
	
	protected void updateProx(MentalObject mO) {
		Vector2 myPos = new Vector2 (gameObject.transform.position.x, gameObject.transform.position.y);
		Vector2 otherPos = new Vector2(mO.Obj.transform.position.x, mO.Obj.transform.position.y);
		float rawProx = (myPos-otherPos).sqrMagnitude;
		mO.Prox = 1 - (rawProx-MIN_DIST)/(MAX_DIST-MIN_DIST);
	}
}
